#include "includes.h"
#include "usart5.h"
  

//串口接收缓存区 	
OS_EVENT * USART5_Recv_Sem;

typedef struct _st_USART5_RX {
	UINT8 qbuf[128];
	UINT32 qlen;

	UINT8 buf[128];
	UINT32 len;
		
	UINT32 GetFlag;
}st_USART5_RX;

st_USART5_RX  USART5_RX;

enum{
	FLAG_RX_FULL		= (1<<0),
	FLAG_RX_END			= (1<<1),
	FLAG_RX_OVERLAP 	= (1<<2),
	FLAG_RX_IDLE		= 0,
};






/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: USART5_IRQHandler
** 功能描述: 通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
					//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
					//任何数据,则表示此次接收完毕.
					//接收到的数据状态
					//[15]:0,没有接收到数据;1,接收到了一批数据.
					//[14:0]:接收到的数据长度
** 参数描述：无
** 作  　者: msl
** 日　  期: 2015年12月18日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void UART5_IRQHandler(void)                	//串口1中断服务程序
	{
	u8 Res;
	OSIntEnter();    
	if(USART_GetITStatus(UART5, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
	{

	
		Res =USART_ReceiveData(UART5);	//读取接收到的数据		
		if (USART5_RX.qlen < sizeof(USART5_RX.qbuf))
		{
			USART5_RX.qbuf[USART5_RX.qlen] = Res;	
			USART5_RX.qlen++;
		}	  
		else
		{
			USART5_RX.GetFlag |= FLAG_RX_FULL;
		}					 
   } 
	
	if(USART_GetITStatus(UART5, USART_IT_IDLE) != RESET)
    {
        USART_ReceiveData(UART5);  
        USART_ClearITPendingBit(UART5,USART_IT_IDLE);
		if (USART5_RX.GetFlag & FLAG_RX_END)
		{
			USART5_RX.GetFlag |= FLAG_RX_OVERLAP;
		}	
		else
		{
			USART5_RX.GetFlag |= FLAG_RX_END;
		}	
		
	
		if (USART5_RX.qlen > 0)
		{	

			memcpy(USART5_RX.buf, USART5_RX.qbuf, USART5_RX.qlen);
			
			USART5_RX.len = USART5_RX.qlen;
			USART5_RX.qlen = 0;
			
			OSSemPost(USART5_Recv_Sem);
		}
	}
	OSIntExit();  											 
} 






/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: usart5_init
** 功能描述: 初始化IO 串口5
** 参数描述：PCLK1时钟频率(Mhz)
						 bound:波特率	
** 作  　者: msl
** 日　  期: 2015年12月18日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void usart5_init(u32 bound)
{  

	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);	// GPIOB时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);	// GPIOB时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE); //串口5时钟使能

 	USART_DeInit(UART5);  //复位串口5

	    /*UART5  TXD*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	/*UART5 RX */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	
	USART_InitStructure.USART_BaudRate = bound;//波特率一般设置为9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式
  
	USART_Init(UART5, &USART_InitStructure); //初始化串口	5
  

	USART_Cmd(UART5, ENABLE);                    //使能串口 
	
	//使能接收中断
	USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启中断 
	USART_ITConfig(UART5, USART_IT_IDLE, ENABLE);
	//USART_ITConfig(USART5, USART_IT_TXE , ENABLE);//开启中断  

	
	//设置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级5
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//子优先级5
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
	
	//TIM4_Int_Init(99,7199);		//10ms中断
	//TIM_Cmd(TIM4,DISABLE);			//关闭定时器7
}






/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: USART1_Read
** 功能描述: 串口1接收数据
** 参数描述：无
** return	 : 返回1表示接收到数据，0表示没有接收到数据
** 作  　者: msl
** 日　  期: 2015年12月18日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
INT32 USART5_Read(UINT8 *BUF, UINT32 len, UINT32 timeout)
{
	INT32 ret;
    UINT8 err = 0;	
	UINT32 tlen = 0;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
		OS_CPU_SR  cpu_sr = 0u;
#endif		
	OSSemPend(USART5_Recv_Sem, timeout, &err); 
	if (err == OS_ERR_NONE)
	{
		OS_ENTER_CRITICAL();
		if (len < USART5_RX.len)
		{
			tlen = len;
		}	
		else
		{
			tlen = USART5_RX.len;
		}	
		memcpy(BUF,USART5_RX.buf, tlen);
		USART5_RX.GetFlag &= (~(FLAG_RX_END|FLAG_RX_OVERLAP));		
		ret = tlen;
		USART5_RX.len = 0;
		OS_EXIT_CRITICAL();	
	}	
	else
	{
		ret = -1;
	}	
	return ret;
}

INT32 USART5_Read_NoBlock(UINT8 *BUF, UINT32 len)
{
	INT32 ret;	
	UINT32 tlen = 0;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
		OS_CPU_SR  cpu_sr = 0u;
#endif		
	if (OSSemAccept(USART5_Recv_Sem) > 0)
	{
		OS_ENTER_CRITICAL();
		if (len < USART5_RX.len)
		{
			tlen = len;
		}	
		else
		{
			tlen = USART5_RX.len;
		}	
		memcpy(BUF,USART5_RX.buf, tlen);
		USART5_RX.GetFlag &= (~(FLAG_RX_END|FLAG_RX_OVERLAP));		
		ret = tlen;
		USART5_RX.len = 0;
		OS_EXIT_CRITICAL();	
	}	
	else
	{
		ret = -1;
	}	
	return ret;
}

INT32 USART5_Write(UINT8 *BUF, UINT32 len)
{
UINT32	j = 0;
UINT32  i = 0;	
	for(j=0;j<len;j++)							//循环发送数据
	{
		while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET)
		{//循环发送,直到发送完毕 
			i++;
			if (i > 2000*1000)
				break;
		}			  
		USART_SendData(UART5,BUF[j]); 
	} 	
	return 0;
}



void USART5_CLEAR_RX(void)
{
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */
		OS_CPU_SR  cpu_sr = 0u;
#endif		
	OS_ENTER_CRITICAL();
	USART5_RX.GetFlag = FLAG_RX_IDLE;	
	USART5_RX.len = 0;
	USART5_RX.qlen = 0;
	USART5_Recv_Sem->OSEventCnt = 0;
	OS_EXIT_CRITICAL();		
}	


void USART5_Create_Sem(void)
{	
#if OS_CRITICAL_METHOD == 3u
    OS_CPU_SR cpu_sr=0u;
#endif
    OS_ENTER_CRITICAL();  //进入临界区(关闭中断)   
	USART5_Recv_Sem = OSSemCreate(0); 
    OS_EXIT_CRITICAL();  //退出临界区(开中断)
}




#if 0
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称:u5_printf
** 功能描述: printf 函数
** 参数描述：
** 作  　者: msl
** 日　  期: 2015年12月18日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
//确保一次发送数据不超过USART5_MAX_SEND_LEN字节

void u5_printf(char* fmt,...)  
{  
	u16 i,j; 
	va_list ap; 
	va_start(ap,fmt);
	vsprintf((char*)USART5_TX_BUF,fmt,ap);
	va_end(ap);
//	USART5_TX_STA = strlen((const char*)USART5_TX_BUF);		//此次发送数据的长度
//	USART_ITConfig(USART5, USART_IT_TXE, ENABLE);
//	USART_ClearITPendingBit(USART5,USART_IT_RXNE); //清除中断标志
//  USART_SendData(USART5, USART5_TX_BUF[0]); 
	i=strlen((const char*)USART5_TX_BUF);		//此次发送数据的长度
	for(j=0;j<i;j++)							//循环发送数据
	{
	  while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕   
		USART_SendData(UART5,USART5_TX_BUF[j]); 
	} 
}

void u5_Send(u8 *data, u8 len)
{
	u16 j; 
#if DEBUG
	printf("S5:\r\n");
#endif	
	for(j=0;j<len;j++)							//循环发送数据
	{
	  while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕   
				USART_SendData(UART5,data[j]); 
#if DEBUG		
		uart1_puthex(data[j]);
#endif		
	} 
#if DEBUG
	printf("\r\n");
#endif
//		memcpy(USART5_TX_BUF,data,len);

//		USART_ITConfig(USART5, USART_IT_TXE, ENABLE);
//		USART_ClearITPendingBit(USART5,USART_IT_RXNE); //清除中断标志
//		USART5_TX_STA = len;
//  //  USART_SendData(USART5, USART5_TX_BUF[0]); 
}
 






#endif

